package imp.avos;

import java.util.List;

import base.display.model.IGetDataListener;
import base.utils.Logger;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.DeleteCallback;
import com.avos.avoscloud.FindCallback;
import com.avos.avoscloud.GetCallback;
import com.avos.avoscloud.SaveCallback;

public class AVFakeServer {

	private static final String TAG = AVFakeServer.class.getSimpleName();

	public void excute(BAVObject request, final IGetDataListener<BAVObject, BAVObject> listener) {
		switch (request.getRequestType()) {
		case SAVE:
			doSave(request, listener);
			break;
		case DELETE:
			doDelete(request, listener);
			break;
		case GET_ITEM:
			doGetItem(request, listener);
			break;
		case GET_LIST:
			doGetList(request, listener);
			break;
		default:
			break;
		}
	}

	@SuppressWarnings("unchecked")
	private void doSave(final BAVObject request, final IGetDataListener<BAVObject, BAVObject> listener) {
		// TODO Auto-generated method stub
		Logger.verbose(TAG, "doSave -> " + request);
		request.assembleSaveData();
		SaveCallback callback = new SaveCallback() {

			@Override
			public void done(AVException avexception) {
				// TODO Auto-generated method stub
				if (avexception == null) {
					listener.onFinish(request, request);
				} else {
					listener.onError(request, avexception);
				}
			}
		};
		List<AVObject> list = request.getSaveList() == null ? null : (List<AVObject>) request.getSaveList();
		if (list != null && list.size() > 0) {
			for (AVObject av : list) {
				Logger.verbose(TAG, "\t found -> " + av.getObjectId());
				av.setFetchWhenSave(true);
			}
			AVObject.saveAllInBackground(list, callback);
		} else {
			Logger.verbose(TAG, "\t found -> " + request.getObjectId());
			request.setFetchWhenSave(true);
			request.saveInBackground(callback);
		}
	}

	@SuppressWarnings("unchecked")
	private void doDelete(final BAVObject request, final IGetDataListener<BAVObject, BAVObject> listener) {
		// TODO Auto-generated method stub
		Logger.verbose(TAG, "doDelete -> " + request);
		request.onAssembleDeleteData();
		request.setFetchWhenSave(true);
		final List<AVObject> list = request.getDeleteList() == null ? null : (List<AVObject>) request.getDeleteList();
		DeleteCallback callback = new DeleteCallback() {

			@Override
			public void done(AVException avexception) {
				// TODO Auto-generated method stub
				if (avexception == null) {
					if (list != null) {
						for (AVObject o : list) {
							o.setObjectId(null);
						}
					}
					request.setObjectId(null);
					listener.onFinish(request, request);
				} else {
					listener.onError(request, avexception);
				}
			}
		};
		if (list != null && list.size() > 0) {
			for (AVObject av : list) {
				Logger.verbose(TAG, "\t found -> " + av.getObjectId());
				av.setFetchWhenSave(true);
			}
			AVObject.deleteAllInBackground(list, callback);
		} else {
			Logger.verbose(TAG, "\t found -> " + request.getObjectId());
			request.deleteInBackground(callback);
		}
	}

	private <Response extends BAVObject> void doGetItem(final BAVObject request, final IGetDataListener<BAVObject, BAVObject> listener) {
		// TODO Auto-generated method stub
		Logger.verbose(TAG, "doGetItem -> " + request);
		AVQuery<Response> query = AVQuery.getQuery(request.getTableName());
		request.onAssembleSearchCondition(query);
		query.getInBackground(request.getObjectId(), new GetCallback<Response>() {

			@Override
			public void done(Response arg0, AVException arg1) {
				// TODO Auto-generated method stub
				if (arg1 == null) {
					Logger.verbose(TAG, "\t arg0 -> " + arg0);
					if (arg0 != null) {
						arg0.convert();
					}
					listener.onFinish(request, arg0);
				} else {
					listener.onError(request, arg1);
				}
			}
		});
	}

	@SuppressWarnings("unchecked")
	private <Response extends BAVObject> void doGetList(final BAVObject request, final IGetDataListener<BAVObject, BAVObject> listener) {
		// TODO Auto-generated method stub
		Logger.verbose(TAG, "doGetList -> " + request);
		AVQuery<Response> query = AVQuery.getQuery(request.getTableName());
		request.onAssembleSearchCondition(query);
		query.findInBackground(new FindCallback<Response>() {

			@Override
			public void done(List<Response> arg0, AVException arg1) {
				// TODO Auto-generated method stub
				if (arg1 == null) {
					if (arg0 != null) {
						request.setList((List<BAVObject>) arg0);
						for (Response data : arg0) {
							data.convert();
						}
					}
					listener.onFinish(request, request);
				} else {
					listener.onError(request, arg1);
				}
			}
		});
	}

}
